#/usr/bin/python27
#-*- coding: utf-8 -*-
#  Copyright 2011-2013 wuweihui@cn.ibm.com
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import os, sys, re
import pickle
import ConfigParser
import wx
import wx.aui
import  wx.lib.mixins.listctrl  as  listmix

try:
   from agw import aui
except ImportError: # if it's not there locally, try the wxPython lib.
   import wx.lib.agw.aui as aui
   
from mofparser import *

configfile = 'mofconfig.cfg'
mofdir = ''

def prepare():
   global mofdir
   global mofclasslist
   global classfile
   
   if not mofdir:
      config = ConfigParser.RawConfigParser()
      try:
         config.read(configfile)
         mofdir = config.get('mofdir', config.options("mofdir")[0])
      except:
         mofdir = ''
         #print 'Please Add MOF directory first!'
   classfile = ''
   mofclasslist = []
   if mofdir:
       classfile = os.path.join(mofdir, "ClassFile.dc")
       #for test
       #classfile =  "ClassFile.dc"
       try:
          with open(classfile, 'rb') as fp:
             mofclasslist = pickle.load(fp)
       except IOError, e:
          collect_info(mofdir)
      
def collect_info(mofdir, force=False):
   global mofclasslist
   
   mofclasslist = []
   
   for root, dirs, files in os.walk(mofdir):
      for fn in files:
         if fn.lower().endswith('.mof'):
             cl = read_mof(os.path.join(root, fn))
             mofclasslist.extend(cl)
   mofclasslist.sort(cmp=mof_class_cmp)
   for i in range(len(mofclasslist)-1, 0, -1):
      if mofclasslist[i].name == mofclasslist[i-1].name:
         mofclasslist.pop(i)
   with open(classfile, 'wb') as fp:
      pickle.dump(mofclasslist, fp)
      
def get_class_by_name(cn):
   for c in mofclasslist:
      if c.name == cn:
         return c
   return None
   
   
class MyFileDropTarget(wx.FileDropTarget):
   def __init__(self, win):
      wx.FileDropTarget.__init__(self)
      self.win = win
      
   def OnDropFiles(self, x, y, filenames):
      fpath = filenames[0]
      self.win.spathtc.SetValue(fpath)
      
      
class wxHelperFrame(wx.Frame):
   def __init__(self, parent, id=-1):
      wx.Frame.__init__(self, parent, id, 'MOF Reader by wuweihui', size = (970, 720))
      self.SetMinSize((640,480))
      
      self.panel = wx.Panel(self, -1)
      self.panel.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Courier New'))
      
      self.mgr = wx.aui.AuiManager()
      self.mgr.SetManagedWindow(self.panel)
      
      self.SetStatusBar(wx.StatusBar(self, -1))
      self.StatusBar.SetFieldsCount(2)
      self.StatusBar.SetStatusWidths([-2, -1])
      self.SetStatusText("wuweihui@cn.ibm.com", 1)
      
      leftPanel = wx.Panel(self.panel, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN)
      self.searchctrl = wx.SearchCtrl(leftPanel, size=(200,-1), style=wx.TE_PROCESS_ENTER)
      self.searchctrl.ShowSearchButton(True)
      self.searchctrl.ShowCancelButton(True)
      self.indexlb = wx.ListBox(leftPanel, -1, style=wx.LB_SINGLE)
      
      self.parentlb = wx.ListBox(leftPanel, -1, size=(0, 25))
      self.childlb = wx.ListBox(leftPanel, -1, style=wx.LB_SINGLE)
      
      space = 5
      
      leftsizer = wx.BoxSizer(wx.VERTICAL)
      leftsizer.Add(self.searchctrl, 0, wx.EXPAND|wx.ALL, space)
      leftsizer.Add(self.indexlb, 1, wx.EXPAND, space)
      leftsizer.Add(self.parentlb, 0, wx.EXPAND, space)
      leftsizer.Add(self.childlb, 0, wx.EXPAND, space)
      leftPanel.SetSizer(leftsizer)
      leftPanel.Fit()
      
      
      self.nb = wx.aui.AuiNotebook(self.panel)
      welcometc = wx.TextCtrl(self.nb, -1, 'Welcome', style=wx.TE_MULTILINE)
      self.nb.AddPage(welcometc, 'Welcome')
      
      self.findext = wx.Panel(self.panel, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN)
      self.findtextctrl = wx.TextCtrl(self.findext, -1, '')
      findnextbutton = wx.Button(self.findext, -1, 'Next')
      #findcancelbutton = wx.Button(self.findext, -1, 'Cancel')
      extsizer = wx.BoxSizer(wx.HORIZONTAL)
      extsizer.Add(self.findtextctrl, 1, wx.EXPAND|wx.ALL, space)
      extsizer.Add(findnextbutton, 0, wx.EXPAND, space)
      #extsizer.Add(findcancelbutton, 0, wx.EXPAND, space)
      self.findext.SetSizer(extsizer)
      self.findext.Fit()
      
      self.functionsearchext = wx.Panel(self.panel, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN)
      self.functionsearchctrl = wx.TextCtrl(self.functionsearchext, -1, '', size=(200, -1))
      functionsearchbutton = wx.Button(self.functionsearchext, -1, 'Search')
      extsizer = wx.BoxSizer(wx.HORIZONTAL)
      extsizer.Add(self.functionsearchctrl, 1, wx.EXPAND|wx.ALL, space)
      extsizer.Add(functionsearchbutton, 0, wx.EXPAND, space)
      self.functionsearchext.SetSizer(extsizer)
      self.functionsearchext.Fit()
      
      self.cimcreator = CIMCreater(self.panel, -1)
      
      self.mgr.AddPane(self.nb, wx.aui.AuiPaneInfo().CenterPane().Name("Notebook"))
      self.mgr.AddPane(leftPanel,
                       wx.aui.AuiPaneInfo().
         Left().Layer(2).BestSize((240, -1)).
         MinSize((160, -1)).
         Floatable(False).FloatingSize((240, 700)).
         Caption("MOF Class List").
         CloseButton(False).
         Name("ContrlTree"))
      self.mgr.AddPane(self.cimcreator,
                       wx.aui.AuiPaneInfo().
         Bottom().Layer(2).
         CloseButton(True).BestSize((240, 240)).
         Caption("Functions and parameters").
         Name("CIMCreator"))
      self.mgr.AddPane(self.findext,
                       wx.aui.AuiPaneInfo().
         Right().Layer(3).Position(3).Row(3).
         Floatable(True).
         CloseButton(True).
         Float().Hide().
         Name("FindText"))
      self.mgr.AddPane(self.functionsearchext,
                       wx.aui.AuiPaneInfo().
         Right().Layer(3).Position(3).Row(3).
         Floatable(True).
         CloseButton(True).
         Float().Hide().
         Name("SearchFunction"))
         
      self.mgr.Update()
      
      self.mgr.SetFlags(self.mgr.GetFlags() ^ wx.aui.AUI_MGR_TRANSPARENT_DRAG)
      
      self.CreateMenu()
      
      
      #Bind events
      self.searchctrl.Bind(wx.EVT_TEXT, self.OnSearch)
      self.searchctrl.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.OnSearchCancelBtn)
      self.indexlb.Bind(wx.EVT_LISTBOX_DCLICK, self.OnViewClass)
      self.parentlb.Bind(wx.EVT_LISTBOX_DCLICK, self.OnParent)
      self.childlb.Bind(wx.EVT_LISTBOX_DCLICK, self.OnChild)
      findnextbutton.Bind(wx.EVT_BUTTON, self.OnFindText)
      functionsearchbutton.Bind(wx.EVT_BUTTON, self.OnSearchFuncion)
      self.nb.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChange)
      
      self.InitData()
      
   def CreateMenu(self):
      ID_Refresh = wx.NewId()
      ID_CloseAll = wx.NewId()
      ID_ExportClass = wx.NewId()
      ID_ExportFunction = wx.NewId()
      ID_EXportFuncMap = wx.NewId()
      menubar = wx.MenuBar()
      actionmenu = wx.Menu()
      actionmenu.Append(ID_Refresh, "&Refresh", "Refresh mof definitions")
      actionmenu.Append(ID_ExportClass, "&Export Classes", "Export Classes")
      actionmenu.Append(ID_ExportFunction, "Export &Functions", "Export Functions")
      actionmenu.Append(ID_EXportFuncMap, "Export Function Map", "Export Function Map")
      actionmenu.Append(ID_CloseAll, "&Close All", "Close All windows")
      menubar.Append(actionmenu, '&Action')
      
      ID_ChangDir = wx.NewId()
      ID_AddDir = wx.NewId()
      setmenu = wx.Menu()
      self.dirmenu = wx.Menu()
      setmenu.AppendMenu(ID_ChangDir, "&Change Dir", self.dirmenu)
      setmenu.Append(ID_AddDir, "&Add Dir", "")
      menubar.Append(setmenu, '&Settings')
      
      ID_ShowEditor = wx.NewId()
      viewmenu = wx.Menu()
      viewmenu.Append(ID_ShowEditor, "&Funcions", "")
      menubar.Append(viewmenu, '&View')
      
      ID_FunctionSearch = wx.NewId()
      searchmenu = wx.Menu()
      searchmenu.Append(ID_FunctionSearch, "&Search Function", "")
      menubar.Append(searchmenu, 'Search')
      
      self.config = ConfigParser.RawConfigParser()
      try:
          self.config.read(configfile)
          for op in self.config.options('mofdir'):
             dirname = self.config.get('mofdir', op)
             menuid = wx.NewId()
             self.dirmenu.Append(menuid, dirname, "", wx.ITEM_RADIO)
             self.Bind(wx.EVT_MENU, self.OnChangeDir, id=menuid)
          self.SetStatusText(mofdir, 0)
      except Exception, e:
          pass
      
      self.SetMenuBar(menubar)
      
      self.Bind(wx.EVT_MENU, self.OnRefresh, id=ID_Refresh)
      self.Bind(wx.EVT_MENU, self.OnCloseAll, id=ID_CloseAll)
      self.Bind(wx.EVT_MENU, self.OnAddDir, id=ID_AddDir)
      self.Bind(wx.EVT_MENU, self.OnViewCmd, id=ID_ShowEditor)
      self.Bind(wx.EVT_MENU, self.OnSearchShow, id=ID_FunctionSearch)
      self.Bind(wx.EVT_MENU, self.OnExportClass, id=ID_ExportClass)
      self.Bind(wx.EVT_MENU, self.OnExportFunction, id=ID_ExportFunction)
      self.Bind(wx.EVT_MENU, self.OnExportFunctionMap, id=ID_EXportFuncMap)
      
   def InitData(self):
      self.indexlb.SetItems([k.name for k in mofclasslist])
      
   def OnRefresh(self, evt):  
      collect_info(mofdir)    
      self.indexlb.SetItems([k.name for k in mofclasslist])
      
   def OnCloseAll(self, evt):
      for i in range(self.nb.GetPageCount(), 0, -1):
         self.nb.DeletePage(i-1)
         
   def OnAddDir(self, evt):
      dlg = wx.DirDialog(self, "Choose a directory:",
                          style=wx.DD_DEFAULT_STYLE
      #| wx.DD_DIR_MUST_EXIST
      #| wx.DD_CHANGE_DIR
                           )
      if dlg.ShowModal() == wx.ID_OK:
         newpath = dlg.GetPath()
         oplist = []
         try:
             oplist = self.config.options('mofdir')
         except ConfigParser.NoSectionError, e:
             pass
         for op in oplist:
            if newpath == self.config.get('mofdir', op):
               self.OnChangeDir(newpath)
               return
         nop = "Last"
         for i in range(200):
            if 'dir'+str(i) not in oplist:
               nop = 'dir'+str(i)
               break
         if not self.config.has_section('mofdir'):
             self.config.add_section('mofdir')
         self.config.set('mofdir', nop, newpath)
         
         
         with open(configfile, 'wb') as fp:
            self.config.write(fp)
            
         menuid = wx.NewId()
         self.dirmenu.Append(menuid, newpath, "", wx.ITEM_RADIO)
         self.Bind(wx.EVT_MENU, self.OnChangeDir, id=menuid)
         self.OnChangeDir(newpath)
         
      dlg.Destroy()
      
      
   def OnChangeDir(self, evt):
      global mofdir
      if isinstance(evt, str) or isinstance(evt, unicode):
         mofdir = evt
      else:
         id = evt.GetId()
         mofdir = self.dirmenu.GetLabelText(id)
         
      self.OnCloseAll('')
      prepare()
      self.SetStatusText(mofdir, 0)
      self.indexlb.SetItems([k.name for k in mofclasslist])
      
   def OnViewCmd(self, evt):
      self.mgr.GetPane("CIMCreator").Show()
      self.mgr.Update()
      pi = self.nb.GetSelection()
      if pi != -1 and self.nb.GetPageText(pi) != 'Welcome':
         self.cimcreator.RefreshFunctions(get_class_by_name(self.nb.GetPageText(pi)))
         
   def OnSearch(self, evt):
      sk = self.searchctrl.GetValue().strip().lower()
      if sk:
         matchlist = []
         if sk.count('*') == 0:
            for c in mofclasslist:
               if sk in c.lwname:
                  matchlist.append(c.name)
         else:
            sk = sk.replace('*', '.*')
            for c in mofclasslist:
               if re.match(sk, c.lwname):
                  matchlist.append(c.name)
         self.indexlb.SetItems(matchlist)
      else:
         self.indexlb.SetItems([k.name for k in mofclasslist])
         
   def OnSearchCancelBtn(self, evt):
      self.searchctrl.SetValue('')
      
   def OnViewClass(self, evt):
      if isinstance(evt, str) or isinstance(evt, unicode):
         cn = evt
      else:
         cn = self.indexlb.GetStringSelection()
         
         #refresh parent and child
      self.parentlb.SetItems([])
      #self.childlb.SetItems([])
      childlist = []
      self.mc = None
      for c in mofclasslist:
         if c.name == cn:
            self.mc = c
         if c.parent == cn:
            childlist.append(c.name)
            
      if self.mc.parent:
         self.parentlb.SetItems([self.mc.parent])
         
      self.childlb.SetItems(childlist)
      
      #print dir(self.mgr.GetPane("CIMCreator"))
      
#      if self.mgr.GetPane("CIMCreator").IsShown():
#         self.cimcreator.RefreshFunctions(self.mc)
         
      for i in range(self.nb.GetPageCount()):
         pagetext = self.nb.GetPageText(i)
         if cn == pagetext:
            self.nb.SetSelection(i)
            return
      src = self.mc.get_src()
      newpage = wx.TextCtrl(self.nb, -1, self.mc.fn+'\n\n'+src, style=wx.TE_MULTILINE)
      newpage.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Courier New'))
      newpage.SetEditable(False)
      newpage.Bind(wx.EVT_KEY_DOWN, self.OnTextFind)
      self.nb.AddPage(newpage, cn)
      self.nb.SetSelection(self.nb.GetPageIndex(newpage))
      
   def OnPageChange(self, evt):
      pagetext = self.nb.GetPageText(self.nb.GetSelection())
      if pagetext != 'Welcome':
         self.mc = get_class_by_name(pagetext)
      if self.mgr.GetPane("CIMCreator").IsShown():
         self.cimcreator.RefreshFunctions(self.mc)
      evt.Skip()
      
   def OnParent(self, evt):
      cn = self.parentlb.GetStringSelection()
      #print cn, type(cn)
      self.OnViewClass(cn)
      
   def OnChild(self, evt):
      cn = self.childlb.GetStringSelection()
      self.OnViewClass(cn)
      
   def OnTextFind(self, evt):
   #print dir(evt)
      if evt.ControlDown() and evt.GetKeyCode() == 70:
         self.curpage = evt.GetEventObject()
         self.fstartpos = 0
         
         pt = self.curpage.ClientToScreen(wx.Point(0, 0))
         self.mgr.GetPane("FindText").Show().FloatingPosition((pt.x+50, pt.y+50))
         self.mgr.Update()
         self.findtextctrl.SetFocus()
      if evt.ControlDown() and evt.GetKeyCode() == 83:
         self.OnSearchShow('')
      evt.Skip()
      
   def OnFindText(self, evt):
      sk = self.findtextctrl.GetValue().lower().strip()
      if sk:
         src = self.curpage.GetValue().lower()
         pos = src.find(sk, self.fstartpos)
         #print sk, pos
         if pos != -1:
            self.curpage.SetFocus()
            ppos = pos + src[:pos].count('\n')
            self.curpage.ShowPosition(ppos+len(sk))
            self.curpage.SetSelection(ppos, ppos+len(sk))
            self.fstartpos = pos + len(sk)
         else:
            if self.fstartpos == 0:
               return
            else:
               self.fstartpos = 0
      pass
   
   def OnSearchShow(self, evt):
      pt = self.nb.ClientToScreen(wx.Point(0, 0))
      self.mgr.GetPane("SearchFunction").Show().FloatingPosition((pt.x+50, pt.y+50))
      self.functionsearchctrl.SetFocus()
      self.mgr.Update()
   
   def OnSearchFuncion(self, evt):
      sk = self.functionsearchctrl.GetValue()
      self.functionsearchctrl.SetValue('')
      self.mgr.GetPane("SearchFunction").Hide()
      self.mgr.Update()
      if sk.strip():
         self.SearchFunction(sk)
   
   def SearchFunction(self, fname):
      sk = fname.strip().lower()
      if sk:
         matchlist = []
         if sk.count('*') == 0:
            for c in mofclasslist:
               for f in c.functions:                  
                  if sk in f.name.lower():
                     matchlist.append(c.name)
                     break
         else:
            sk = sk.replace('*', '.*')
            for c in mofclasslist:
               for f in c.functions:
                  if re.match(sk, f.name.lower()):
                     matchlist.append(c.name)
                     break
         self.indexlb.SetItems(matchlist)
      
   def SelectLineOnPage(self, pos):
      pos = pos + len(self.mc.fn) + 2
      page = self.nb.GetPage(self.nb.GetSelection())
      src = page.GetValue()
      ln = src[:pos].count('\n')
      en = src.find('\n', pos)
      if en == -1:
         en = len(src)
      else:
         en = en + ln
      page.ShowPosition(pos + ln)
      page.SetSelection(pos + ln, en)
      page.SetFocus()
      pass
      
   txtwildcard = "Txt file (*.txt)|*.txt|"        \
              "All files (*.*)|*.*"
   def OnExportClass(self, evt):
      dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=os.getcwd(), 
                          defaultFile="", wildcard=self.txtwildcard, style=wx.SAVE)
      if dlg.ShowModal() == wx.ID_OK:
         path = dlg.GetPath()
         with open(path, 'wb') as fp:
            fp.write('\n'.join(self.indexlb.GetItems()))
      dlg.Destroy()
   
   def OnExportFunction(self, evt):
      dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=os.getcwd(), 
                          defaultFile="", wildcard=self.txtwildcard, style=wx.SAVE)
      if dlg.ShowModal() == wx.ID_OK:
         path = dlg.GetPath()
         with open(path, 'wb') as fp:
            for cn in self.indexlb.GetItems():
               c = get_class_by_name(cn)
               if c.functions:
                  fp.write('\n'.join([cn+'.'+f.name for f in c.functions]) + '\n')
      dlg.Destroy()
      
   def OnExportFunctionMap(self, evt):
      dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=os.getcwd(), 
                          defaultFile="", wildcard=self.txtwildcard, style=wx.SAVE)
      if dlg.ShowModal() == wx.ID_OK:
         path = dlg.GetPath()
         with open(path, 'wb') as fp:
            for cn in self.indexlb.GetItems():
               c = get_class_by_name(cn)
               if c.functions:
                  for f in c.functions:
                     prefix = '"%s.%s": {' % (f.name, cn)
                     fp.write(prefix + '\n')
                     for arg in f.args:
                        values = '[""]'
                        name = arg.name
                        if arg.type.startswith("IBMTS") or arg.type.startswith("CIM_") \
                        or arg.type.startswith("PG_") or arg.type.startswith("PRS_") \
                        or arg.type.startswith("SNIA_"):
                           values = '[get_cim_key_list, "%s"]' % arg.type
                           name = arg.name+'(REF)'
                        fp.write(" "*len(prefix) + '"%s": %s,\n' % (name, values))
                     fp.write(" "*len(prefix) + '},\n')
      dlg.Destroy()
   
class ListEditor(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.TextEditMixin):
   def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize,
                style=wx.LC_REPORT | wx.LC_NO_HEADER):
      wx.ListCtrl.__init__(self, parent, id, pos, size, style)
      listmix.ListCtrlAutoWidthMixin.__init__(self)
      self.InsertColumn(0, 'Value')
      self.SetColumnWidth(0, 300)
      #self.InsertStringItem(sys.maxint, "teststring")
      listmix.TextEditMixin.__init__(self)
      self.SetFont(wx.Font(7, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Courier New'))
      pass
      
   def SetItems(self, items):
      self.DeleteAllItems()
      for item in items:
         self.InsertStringItem(sys.maxint, str(item))
         
   def DeSelectAll(self):
      for i in range(self.GetItemCount()):
         self.Select(i, False)
         
class CIMCreater(wx.Panel):
   def __init__(self, parent, id=-1):
      wx.Panel.__init__(self, parent, id, style=wx.TAB_TRAVERSAL|wx.CLIP_CHILDREN)
      
      #self.functioncb = wx.ComboBox(self, -1, '', choices=[])
      self.classvarlb = wx.ListBox(self, -1, choices=[], size=[250, -1])
      self.functionlb = wx.ListBox(self, -1, choices=[], size=[250, -1])
      self.parameterlb = wx.ListBox(self, -1, choices=[], size=[250, -1])
      #self.valuele = ListEditor(self, -1)
      self.valuele = wx.ListBox(self, -1, choices=[], size=[200, -1])
      self.ci = -1
      self.fi = -1
      self.cvarvalues = []
      self.pvalues = []
      
      self.cmdtc = wx.TextCtrl(self, -1, '')
      
      vsizer = wx.BoxSizer(wx.VERTICAL)
      space = 5
      hsizer = wx.BoxSizer(wx.HORIZONTAL)
      hsizer.Add(self.classvarlb, 0, wx.EXPAND|wx.ALL, space)
      hsizer.Add(self.functionlb, 0, wx.EXPAND|wx.ALL, space)
      hsizer.Add(self.parameterlb, 0, wx.EXPAND|wx.ALL, space)
      hsizer.Add(self.valuele, 1, wx.EXPAND|wx.ALL, space)
      
      vsizer.Add(hsizer, 1, wx.EXPAND|wx.ALL, 0)
      vsizer.Add(self.cmdtc, 0, wx.EXPAND|wx.ALL, space)
      self.SetSizer(vsizer)
      
      self.classvarlb.Bind(wx.EVT_LISTBOX, self.OnClassVar)
      self.functionlb.Bind(wx.EVT_LISTBOX, self.OnFunction)
      self.parameterlb.Bind(wx.EVT_LISTBOX, self.OnParameter)
      #self.valuele.Bind(wx.EVT_TEXT, self.OnValueChange)
      #self.valuele.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnValueChange)
      self.valuele.Bind(wx.EVT_LISTBOX, self.OnValueChange)
      
      self.Update()
      
   def RefreshFunctions(self, mc):
      self.mc = mc
      self.classvarlb.SetItems([a.name for a in mc.args])
      self.functionlb.SetItems([f.name for f in mc.functions])
      self.parameterlb.SetItems([])
      self.valuele.SetItems([])
      
      self.Update()
      
   def OnClassVar(self, evt):
      varname = self.classvarlb.GetStringSelection()
      for arg in self.mc.args:
         if arg.name == varname:
            self.Parent.Parent.SelectLineOnPage(arg.start)
            break
            
      self.valuele.SetItems([arg.default or 'NULL' for arg in self.mc.args])
      #print index
      #self.valuele.SetFocus()
      self.valuele.DeselectAll()
      self.functionlb.DeselectAll()
      self.parameterlb.DeselectAll()
      #self.valuele.EditLabel(self.valuele.GetItem(index), 0)
      
   def OnFunction(self, evt):
      fn = self.functionlb.GetStringSelection()
      
      self.classvarlb.DeselectAll()
      self.parameterlb.DeselectAll()
      
      #print self.functiondict
      for f in self.mc.functions:
         if f.name == fn:
            self.fun = f
            self.Parent.Parent.SelectLineOnPage(f.start)
            args = f.args
            break
      self.parameterlb.SetItems([arg.io+'|'+arg.name for arg in args])
      errornums = self.fun.errordict.keys()
      errornums.sort()
      self.valuele.SetItems(errornums)
            
   def OnParameter(self, evt):
      argname = self.parameterlb.GetStringSelection().split('|')[-1]
      for arg in self.fun.args:
         if arg.name == argname:
            self.Parent.Parent.SelectLineOnPage(arg.start)
            break
   
#   def OnValueChange(self, evt):
#      if self.functionlb.GetSelection() != -1:
#         for i in range(self.parameterlb.GetCount()):
#            v = self.valuele.GetItem(i).GetText()
#            if re.match(r'\w+', v):
#               if v.count(' ') > 0:
#                  v = '"' + v + '"'
#            if v == 'None':
#               v = ' '
#            self.pvalues[i] = v
#            
#         cmd = self.functionlb.GetStringSelection() + ' '
#         #inout = self.functiondict[cmd]
#         cmd = cmd + ' '.join(self.pvalues)
#         self.cmdtc.SetValue(cmd)

   def OnValueChange(self, evt):
      errornum = self.valuele.GetStringSelection()
      self.cmdtc.SetValue(self.fun.errordict[errornum])
         
         
class App(wx.App):

   def OnInit(self):
      self.frame = wxHelperFrame(None)
      self.frame.Show(True)
      return True
      
if __name__ == "__main__":
   prepare()
   app = App(False)
   app.MainLoop()
   
   